/**
 * Project Name:jh
 * File Name:RXBQTakeThread.java
 * Package Name:com.jh.web
 * Date:下午5:38:16
 * Copyright (c) 2021, LZ All Rights Reserved.
 *
*/

package com.jh.comm;

import java.lang.reflect.Type;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jh.pojo.Entity;
import com.jh.pojo.EntityT;
import com.jh.pojo.IPCamMsg;
import com.jh.pojo.IPCamRadarRetBean;
import com.jh.pojo.RadarMsg;
import com.jh.pojo.RadarObjBean;
import com.jh.pojo.RadarRetBean;
import com.jh.pojo.RadarRetToBsBean;
import com.jh.pojo.RadarSysBean;
import com.jh.pojo.SPInfo;
import com.jh.utils.BlockingQueueUtils;
import com.jh.utils.CacheUtils;

/**
 * Description: <br/>
 * Date: 下午5:38:16 <br/>
 * 
 * @author lz E-mail:withitren@outlook.com
 * @version
 * @see https://github.com/TakahikoKawasaki/nv-websocket-client
 *      https://blog.csdn.net/u013872857/article/details/79190643
 * 
 */
public class RXBQTakeThread extends Thread {
    static final Logger logger = LoggerFactory.getLogger(RXBQTakeThread.class);

    private String SERVER = null;

    private int wsReconnTimeOut;

    WSManager wsManager = null;

    public String getSERVER() {
        return SERVER;
    }

    public void setSERVER(String sERVER) {
        SERVER = sERVER;
    }

    public int getWsReconnTimeOut() {
        return wsReconnTimeOut;
    }

    public void setWsReconnTimeOut(int wsReconnTimeOut) {
        this.wsReconnTimeOut = wsReconnTimeOut;
    }

    private void init() {
        /*read configration from Properties*/
        Properties prop = new Properties();
        try {
            prop.load(RXBQTakeThread.class.getResourceAsStream("/appConfig.properties"));
            // throw new Exception("OK!");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        String wsUrl = prop.getProperty("wsUrl", "ws://localhost:8080/jh/radar");
        String sysWsClientName = prop.getProperty("sysWsClientName", "sysRadarComm001");
        String wsReconnTimeOutStr = prop.getProperty("wsReconnTimeOut", "30000");
        wsReconnTimeOut = Integer.parseInt(wsReconnTimeOutStr);
        String serverString = wsUrl + "?loginName=" + sysWsClientName;
        setSERVER(serverString);
        setWsReconnTimeOut(wsReconnTimeOut);
        System.out.println("sys WsClient Url" + getSERVER() + " wsReconnTimeOut: " + wsReconnTimeOutStr);
        logger.debug("--->" + "sys WsClient Url" + getSERVER() + " wsReconnTimeOut: " + wsReconnTimeOutStr);

        /*create a ws client*/
        wsManager = new WSManager();
        wsManager.setSERVER(getSERVER());
        wsManager.onCreate();

        /*ws连接，直到连上为止，和断开后重连*/
        new Thread(() -> {
            while (true) {
                int connStatus = wsManager.getConnectStatus();
                if (connStatus == 0) {
                    logger.debug("--->" + "reconnect: " + connStatus);
                    wsManager.reconnect();
                    connStatus = wsManager.getConnectStatus();
                }
                try {
                    /*30s reconnect*/
                    Thread.sleep(30 * 1000);
                } catch (InterruptedException e) {
                    logger.error(e.getMessage(), e);
                }
                System.out.println("connStatus: " + connStatus);
                logger.debug("--->" + "connStatus: " + connStatus);
            }
        }).start();

    }

    private void InitRadarRetToBsObj(RadarRetToBsBean obj) {
        obj.setIp(null);
        obj.setError(null);

        obj.setThreshold(null);
        obj.setThreshStatus(null);

        obj.setSpeed(null);
        obj.setPosAngle(null);
        obj.setSwiveResideStatus(null);

        obj.setDirec(null);
        obj.setSwiveControlStatus(null);

        obj.setLedCmd(null);
        obj.setLedCmdStatus(null);
    }

    @Override
    public void run() {
        BlockingQueueUtils queueUtils = BlockingQueueUtils.getInstance();

        ArrayBlockingQueue<String> rxBq = queueUtils.getrxBq();
        logger.debug("--->" + "entern RXBQTakeThread run ");
        init();
        CacheUtils cacheUtils = CacheUtils.getInstance();
        SPInfo spInfo = null;
        RadarMsg radarMsg = null;
        IPCamMsg ipcamMsg = null;
        RadarRetBean retBean = null;
        String take = null;
        Gson g = new Gson();
        EntityT et = null;
        Entity entity = new Entity();
        String json = null;
        int typeFlag = -1;
        Type jsonType;
        String ipIndex = null;
        StringBuilder sb = null;
        RadarRetToBsBean radarRetToBsBean = new RadarRetToBsBean();
        while (true) {
            System.out.println(getName() + " RXBQTakeThread ready to take queue！");
            try {
                // Thread.sleep(200);
                // 尝试取出元素，如果队列为空，则线程被阻塞
                take = rxBq.take();
                System.out.println(" RXBQTakeThread: " + take);
                et = g.fromJson(take, EntityT.class);

                System.out.println("et =" + et.toString());

                System.out.println("et.getType(): " + et.getType());

                typeFlag = et.getType();
                logger.debug("--->" + "typeFlag : " + typeFlag);

                switch (typeFlag) {
                case 1:
                    /*连接雷达命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("1 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }

                    System.out.println("retBean: " + retBean);
                    logger.debug("--->" + "retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());
                    break;
                case 2:
                    /*断开雷达命令反馈）*/

                    break;

                case 3:
                    /*雷达复位命令反馈）*/

                    break;

                case 4:
                    /*清空杂波图命令反馈）*/

                    break;

                case 5:
                    /*预扫描命令反馈）*/

                    break;

                case 6:
                    /*检测扫描命令反馈）*/

                    break;

                case 7:
                    /*转台控制 - 紧急停止命令反馈）*/

                    break;

                case 8:
                    /*转台控制 - 机械归零命令反馈）*/

                    break;

                case 9:
                    /*设置转台水平零位命令反馈）*/

                    break;

                case 10:
                    /*补光灯控制命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("10 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    radarMsg.setrLedCmdStatus(retBean.getError()); // 0表示指令发送成功,1表示指令发送失败，原因是TCP/IP网络故障
                                                                   // ,2表示指令发送失败，原因是此雷达未连接
                    InitRadarRetToBsObj(radarRetToBsBean);
                    radarRetToBsBean.setIp(retBean.getIp());
                    radarRetToBsBean.setError(retBean.getError());
                    radarRetToBsBean.setLedCmd(radarMsg.getrLedCmd());
                    radarRetToBsBean.setLedCmdStatus(retBean.getError()); /*此处的作用和radarRetToBsBean中的error重复*/

                    System.out.println("10 retBean: " + retBean);
                    logger.debug("--->" + "10 retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());
                    // Entity entity = new Entity();
                    entity.setType(10);
                    entity.setData(radarRetToBsBean);

                    try {
                        json = g.toJson(entity);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    take = json;
                    break;

                case 11:
                    /*轉臺手動操作命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("11 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    radarMsg.setrSwivelCtrlStatus(retBean.getError()); // 0表示指令发送成功,1表示指令发送失败，原因是TCP/IP网络故障
                                                                       // ,2表示指令发送失败，原因是此雷达未连接
                    InitRadarRetToBsObj(radarRetToBsBean);
                    radarRetToBsBean.setIp(retBean.getIp());
                    radarRetToBsBean.setError(retBean.getError());
                    radarRetToBsBean.setSpeed(radarMsg.getrSwivelCtrlSpd());
                    radarRetToBsBean.setDirec(radarMsg.getrSwivelCtrlDir());
                    radarRetToBsBean.setSwiveControlStatus(retBean.getError());
                    System.out.println("11 retBean: " + retBean);
                    logger.debug("--->" + "11 retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());
                    // Entity entity = new Entity();
                    entity.setType(11);
                    entity.setData(radarRetToBsBean);

                    try {
                        json = g.toJson(entity);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    take = json;
                    break;

                case 12:
                    /*單點駐留命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("12 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    radarMsg.setrSwivelResideStatus(retBean.getError()); // 0表示指令发送成功,1表示指令发送失败，原因是TCP/IP网络故障
                                                                         // ,2表示指令发送失败，原因是此雷达未连接
                    InitRadarRetToBsObj(radarRetToBsBean);
                    radarRetToBsBean.setIp(retBean.getIp());
                    radarRetToBsBean.setError(retBean.getError());
                    radarRetToBsBean.setPosAngle(radarMsg.getrSwivelResidePos());
                    radarRetToBsBean.setSpeed(radarMsg.getrSwivelResideSpd());
                    radarRetToBsBean.setSwiveResideStatus(retBean.getError());

                    System.out.println("12 retBean: " + retBean);
                    logger.debug("--->" + "12 retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());
                    // Entity entity = new Entity();
                    entity.setType(12);
                    entity.setData(radarRetToBsBean);

                    try {
                        json = g.toJson(entity);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    take = json;
                    break;

                case 13:
                    /*多點駐留命令反馈）*/

                    break;

                case 14:
                    /*雷达IP配置指令命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("14 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    String newIPFlagStr = retBean.getError();
                    int newIPFlag = Integer.parseInt(newIPFlagStr);
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    radarMsg.setrConfigNewIPStatus(retBean.getError()); // 0表示指令发送成功,1表示指令发送失败，原因是TCP/IP网络故障
                                                                        // ,2表示指令发送失败，原因是此雷达未连接
                    // 反馈有效，需要添加新的IP
                    if (newIPFlag == 0) {

                    }
                    System.out.println("14 retBean: " + retBean);
                    logger.debug("--->" + "14 retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());

                    break;

                case 21:
                    /*设置门限系数命令反馈）*/
                    jsonType = new TypeToken<EntityT<RadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("21 et :" + et.toString());
                    retBean = (RadarRetBean) et.getData();
                    ipIndex = retBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    // 更新雷达配置新阈值的有效性
                    radarMsg.setrSwivelThreshStatus(retBean.getError());
                    System.out.println("retBean: " + retBean);
                    logger.debug("--->" + "21 retBean error: " + retBean.getError() + ", ip :  " + retBean.getIp());

                    InitRadarRetToBsObj(radarRetToBsBean);
                    radarRetToBsBean.setIp(retBean.getIp());
                    radarRetToBsBean.setError(retBean.getError());

                    radarRetToBsBean.setThreshold(radarMsg.getrSwivelThresh());
                    System.out.println("21 radarRetToBsBean: " + radarRetToBsBean.toString());

                    entity.setType(21);
                    entity.setData(radarRetToBsBean);

                    try {
                        json = g.toJson(entity);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                    take = json;
                    break;

                case 22:
                    break;
                case 23:
                    /*接收系统状态反馈）*/
                    jsonType = new TypeToken<EntityT<RadarSysBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("23 et :" + et.toString());
                    RadarSysBean sysBean = (RadarSysBean) et.getData();
                    ipIndex = sysBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    /*向缓存填充参数*/
                    radarMsg.setSysStatus(sysBean.getSysStatus());
                    radarMsg.setSysFaultCause(sysBean.getSysFaultCause());
                    radarMsg.setSysAziAngle(sysBean.getSysAziAngle());
                    radarMsg.setSysClutterMap(sysBean.getSysClutterMap());
                    radarMsg.setSysRebootNum(sysBean.getSysRebootNum());

                    /*System.out.println("23 sysBean IP: " + sysBean.getIp() + " SysStatus: " + sysBean.getSysStatus()
                            + " SysFaultCause: " + sysBean.getSysFaultCause() + " SysAziAngle: "
                            + sysBean.getSysAziAngle() + " SysClutterMap: " + sysBean.getSysClutterMap()
                            + " SysRebootNum:  " + sysBean.getSysRebootNum());*/

                    logger.debug("--->" + "23 sysBean IP: " + sysBean.getIp() + " SysStatus: " + sysBean.getSysStatus()
                            + " SysFaultCause: " + sysBean.getSysFaultCause() + " SysAziAngle: "
                            + sysBean.getSysAziAngle() + " SysClutterMap: " + sysBean.getSysClutterMap()
                            + " SysRebootNum:  " + sysBean.getSysRebootNum());
                    break;

                case 24:
                    /*接收异物信息反馈）*/
                    jsonType = new TypeToken<EntityT<RadarObjBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("24 et :" + et.toString());
                    RadarObjBean objBean = (RadarObjBean) et.getData();
                    ipIndex = objBean.getIp();
                    spInfo = (SPInfo) cacheUtils.query(ipIndex);
                    if (spInfo == null) {
                        break;
                    }
                    radarMsg = spInfo.getRadarMsg();
                    if (radarMsg == null) {
                        break;
                    }
                    ipcamMsg = spInfo.getIpCamMsg();
                    /*向缓存填充参数*/
                    radarMsg.setIp(ipIndex);
                    radarMsg.setObjAzi(objBean.getObjAzi());
                    radarMsg.setObjRange(objBean.getObjRange());
                    radarMsg.setObjAmp(objBean.getObjAmp());
                    radarMsg.setObjAttr(objBean.getObjAttr());
                    radarMsg.setObjTime(objBean.getObjTime());

                    sb = new StringBuilder();
                    // sb.deleteCharAt(sb.length() - 3);
                    // sb.delete(sb.length() - 5, sb.length() - 3);
                    sb.append("},\"ipcamip\":\"");
                    sb.append(ipcamMsg.getIpcamIP());
                    sb.append("\"}");
                    take = take.replace("}}", sb.toString());

                    // 重新组装json字符串，添加ipcam ip字段
                    json = sb.toString();
                    System.out.println("24 sb.toString():" + sb.toString());
                    /*System.out.println("24 ObjBean IP: " + objBean.getIp() + " ObjAzi: " + objBean.getObjAzi()
                            + "ObjRange: " + objBean.getObjRange() + " ObjAmp: " + objBean.getObjAmp() + " ObjAttr: "
                            + objBean.getObjAttr() + " ObjTime:  " + objBean.getObjTime());*/

                    logger.debug("--->" + "24 ObjBean IP: " + objBean.getIp() + " ObjAzi: " + objBean.getObjAzi()
                            + "ObjRange: " + objBean.getObjRange() + " ObjAmp: " + objBean.getObjAmp() + " ObjAttr: "
                            + objBean.getObjAttr() + " ObjTime:  " + objBean.getObjTime());

                    break;

                case 25:
                    /*接收http-flv 播放地址*/
                    jsonType = new TypeToken<EntityT<IPCamRadarRetBean>>() {}.getType();
                    et = g.fromJson(take, jsonType);
                    System.out.println("25 et :" + et.toString());
                    IPCamRadarRetBean ipcamRadarRetBean = (IPCamRadarRetBean) et.getData();
                    ipIndex = ipcamRadarRetBean.getIp(); // ipcam ip
                    Object key = cacheUtils.findKeyByIPCamIP((Object) ipIndex);
                    spInfo = (SPInfo) cacheUtils.query(key);
                    if (spInfo == null) {
                        break;
                    }
                    ipcamMsg = spInfo.getIpCamMsg();
                    if (ipcamMsg == null) {
                        break;
                    }
                    ipcamMsg.setIpcamZMLURL(ipcamRadarRetBean.getUrl());

                    System.out.println("25 ipIndex ipcam: " + ipIndex + " ZMLURL: " + ipcamMsg.getIpcamZMLURL());
                    logger.debug("25 ipIndex ipcam: " + ipIndex + " ZMLURL: " + ipcamMsg.getIpcamZMLURL());
                    break;

                default:
                    System.out.println("error msg " + "typeFlag: " + typeFlag);
                    logger.debug("--->" + "error msg " + "typeFlag: " + typeFlag);
                    break;
                }

                wsManager.sendText(take);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                logger.error(e.getMessage(), e);

            } catch (Exception e1) {
                // TODO Auto-generated catch block
                logger.error(e1.getMessage(), e1);

            }
            logger.debug("--->" + take);
            System.out.println(getName() + " RXBQTakeThread finished to take queue!" + take);
        }
    }

}
